package geektime.concurrent.part2.race;

import java.util.*;

/**
 * 多线程排序计算的工作类
 */
public class MultiThreadComputeWorker implements ComputeRunnable {
    // 需要操作的段位
    private int offset;

    // 需要操作的数据量
    private int size;

    // 需要操作的共享数据
    private MultiThreadShareData shareData;

    public MultiThreadComputeWorker(int offset, int size, MultiThreadShareData shareData) {
        this.offset = offset;
        this.size = size;
        this.shareData = shareData;
    }

    @Override
    public void run() {
        compute();
    }

    @Override
    public void compute() {
        System.out.printf("多线程选手开始计算：offset=%s, size=%s\n", offset, size);
        // 从scoreList中取出需要操作的数据段，将数据转为数组并排序
        int scoreListSize = shareData.getScoreList().size();
        int endIndex = (offset + 1) * size > scoreListSize ? scoreListSize : (offset + 1) * size;
        int actualSize = endIndex - offset * size;
        Integer[] subArray = shareData.getScoreList().subList(offset * size, endIndex).toArray(new Integer[actualSize]);
        // 计算出前10的数字并放入到exchange容器中
        shareData.addExchange(findTop10BySort(subArray));
        // 排序计算的动作完成后，让倒计时门栓countDown
        shareData.getSortComputeLatch().countDown();
    }

    // 通过选择排序法找到前10大的数字
    public static Integer[] findTop10BySort(Integer[] array) {
        // 外层循环次数默认为10次；如果array.length<10则为如果array.length次
        int outerLoopTimes = array.length > 10 ? 10: array.length;
        for (int i = 0; i < outerLoopTimes; i++) {
            for (int j = i + 1; j < array.length; j++) {
                if (array[i] < array[j]) {
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
        return Arrays.copyOf(array, outerLoopTimes);
    }
}
